package net.siufung.mybatis.permit;

import cn.hutool.core.util.StrUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.siufung.core.exception.BizServiceException;
import net.siufung.core.model.enums.DataScopeEnum;
import net.siufung.core.utils.StringPool;
import net.siufung.core.utils.ValidationUtil.ValidResult;
import net.siufung.mybatis.metaobject.MybatisMetaObjectHandler.Constants;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 陈建峰
 * @since 2022/7/25 6:13 下午
 */
public interface MybatisDataPermitService {

    /**
     * 获取数据权限配置列表
     * @return List<DataPermitModel>
     */
    default List<DataPermitModel> getDataPermitModelList() {
        return Lists.newArrayList();
    };

    /**
     * 定义规则
     * @param dataPermitModel 规则模型
     * @param where 返回的where 条件
     * @throws JSQLParserException sql 转换
     * @return Expression 返回条件
     */
    default Expression getDataPermitExpression(DataPermitModel dataPermitModel, Expression where)
            throws JSQLParserException {
        ValidResult validResult = dataPermitModel.validResult();
        if(validResult.hasErrors()){
            throw new BizServiceException(validResult.getErrors());
        }
        if(DataScopeEnum.ALL.equals(dataPermitModel.getDataScopeType())){
            return where;
        }
        if(DataScopeEnum.SELF.equals(dataPermitModel.getDataScopeType())){
            EqualsTo equalsTo = new EqualsTo();
            equalsTo.setLeftExpression(new Column(Strings.isNullOrEmpty(dataPermitModel.getColumn())?
                    Constants.CREATED_BY:dataPermitModel.getColumn()));
            equalsTo.setRightExpression(new StringValue(dataPermitModel.getDataScopeValue()));
            return equalsTo;
        }
        if(DataScopeEnum.DEPT.equals(dataPermitModel.getDataScopeType())){
            EqualsTo equalsTo = new EqualsTo();
            equalsTo.setLeftExpression(new Column(Strings.isNullOrEmpty(dataPermitModel.getColumn())?
                    Constants.CREATED_DEPT:dataPermitModel.getColumn()));
            equalsTo.setRightExpression(new StringValue(dataPermitModel.getDataScopeValue()));
            return equalsTo;
        }
        if (DataScopeEnum.DEPT_AND_CHILD.equals(dataPermitModel.getDataScopeType())){
            List<String> dataScopeValueList = Lists.newArrayList(
                    StrUtil.split(dataPermitModel.getDataScopeValue(), StringPool.COMMA));
            ItemsList itemsList = new ExpressionList(
                    dataScopeValueList.stream().map(StringValue::new).collect(Collectors.toList()));
            return new InExpression(new Column(Strings.isNullOrEmpty(dataPermitModel.getColumn())?
                    Constants.CREATED_DEPT:dataPermitModel.getColumn()), itemsList);
        }
        if (DataScopeEnum.CUSTOMIZE.equals(dataPermitModel.getDataScopeType())){
            return  CCJSqlParserUtil.parseCondExpression(dataPermitModel.getDataScopeValue());
        }
        return where;
    };


}
